/* eslint-disable @typescript-eslint/no-unused-vars */

import { GeoLocate, LineLayer, Marker, Popup, Scene, Zoom } from "@antv/l7";
import { GaodeMapV2 } from "@antv/l7-maps";
import gcoord from "gcoord";
import { getCurrentInstance, ComponentInternalInstance, PropType } from "vue";
import { convertGPS, getAddress, LngLat, MarkerDataInfo } from "../../../utils/gps";
import "./index.scss";
import gpsConvert from "@/utils/gps-convert";
import { MAP_KEY } from "@/config/config";
export default defineComponent({
	props: {
		example: Boolean,
		editerMarker: Boolean,
		detail: {
			type: Object as PropType<MarkerDataInfo>,
			default() {
				return {};
			}
		}
	},
	emits: ["location", "init"],
	setup(props, { emit, expose }) {
		const { proxy } = getCurrentInstance() as ComponentInternalInstance;
		const searchKeywords = ref<string>("");
		const mapContent = reactive<any>({ scene: null, marker: null });
		const mapPlugin = reactive<any>({
			mapSearch: null
		});
		onMounted(() => {
			nextTick(() => {
				if (props.detail.location?.latitude && !props.detail.location?.lat) {
					props.detail.location.lat = props.detail.location.latitude;
				}
				if (props.detail.location?.longitude && !props.detail.location?.lng) {
					props.detail.location.lng = props.detail.location.longitude;
				}
				initPage();
			});
		});
		const initPage = () => {
			// 全局加载高德地图API
			mapContent.scene = new Scene({
				id: "map",
				logoVisible: false,
				antialias: false,
				map: new GaodeMapV2({
					style: "normal", //dark|light|normal|'amap://styles/2a09079c3daac9420ee53b67307a8006?isPublic=true'
					center: [121.4316962, 31.26082325],
					zoom: 12,
					pitch: 15,
					plugin: ["AMap.Geocoder", "AMap.PlaceSearch"],
					token: MAP_KEY
				})
			});
			mapContent.scene.on("loaded", async () => {
				mapContent.scene.addImage("arrow", "https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg");
				loadPlugin();
				initEvents();
				initMarker({ location: props.editerMarker ? props.detail.location || {} : {} }, true);
				// initControl();
				emit("init");
			});
		};
		const searchPlace = () => {
			mapPlugin.mapSearch.search(searchKeywords.value);
		};
		const loadPlugin = () => {
			const geoLocate = new GeoLocate({
				transform: position => {
					// 将获取到基于 WGS84 地理坐标系 的坐标转成 GCJ02 坐标系
					return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
				}
			});
			mapContent.scene.addControl(geoLocate);
			window.AMap.plugin(["AMap.Geocoder", "AMap.PlaceSearch"], () => {
				let amap: any = window.AMap;
				mapPlugin.mapSearch = new amap.PlaceSearch({
					pageSize: 5, // 单页显示结果条数
					pageIndex: 1, // 页码
					map: mapContent.scene.map,
					citylimit: true, //是否强制限制在设置的城市内搜索
					panel: "panel", // 结果列表将在此容器中进行展示。
					autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
				});
				mapPlugin.mapSearch.on("listElementClick", (e: any) => {
					// console.log(e.data);
					// let gcjPt = gpsConvert.gcj_decrypt(e.data.location.lat, e.data.location.lng);
					let info: LngLat = {
						address: e.data.address,
						// lng: gcjPt.lon,
						// lat: gcjPt.lat
						lng: e.data.location.lng,
						lat: e.data.location.lat
					};
					props.detail.location = info;
					addMarker({ location: info }, true);
					//选择搜索项
					mapPlugin.mapSearch.clear();
				});
			});
		};
		const initControl = async () => {
			//定位
			const locateControl: any = new GeoLocate({
				transform: position => {
					// 将获取到基于 WGS84 地理坐标系 的坐标转成 GCJ02 坐标系
					return gcoord.transform(position, gcoord.WGS84, gcoord.GCJ02);
				}
			});
			mapContent.scene.addControl(locateControl);
			let res = await locateControl.getGeoLocation();

			//縮放
			const zoom = new Zoom({
				zoomInTitle: "放大",
				zoomOutTitle: "缩小"
			});
			mapContent.scene.addControl(zoom);
		};
		const initLine = async (dataList: any[]) => {
			let data: any = [{ path: [] }];
			let flag = 0;
			dataList.forEach((item: any) => {
				let gps = item.value && typeof item.value == "string" ? JSON.parse(item.value) : item.value || {};

				// flag += 0.001;
				// item.lng += flag;
				item.lat = gps.lat || gps.latitude;
				item.lng = gps.lng || gps.longitude;
				if (!item.lat || !item.lng || item.lng > 180 || item.lng < -180 || item.lat > 90 || item.lat < -90) {
					return;
				}

				//纠偏
				let gcjPt = gpsConvert.gcj_encrypt(item.lat, item.lng);
				data[0].path.push([gcjPt.lon, gcjPt.lat]);
			});
			if (data[0].path.length) {
				// return;
				let arr = data[0].path;
				//添加轨迹
				const lineLayer = new LineLayer()
					.source(data, {
						parser: {
							type: "json",
							coordinates: "path"
						}
					})
					.size(3)
					.shape("line")
					.texture("arrow")
					.color("rgb(22,119,255)")
					.animate({
						interval: 1, // 间隔
						duration: 1, // 持续时间，延时
						trailLength: 2 // 流线长度
					})
					.style({
						opacity: 1,
						lineTexture: true, // 开启线的贴图功能
						iconStep: 10, // 设置贴图纹理的间距
						borderWidth: 0.4, // 默认文 0，最大有效值为 0.5
						borderColor: "#fff" // 默认为 #ccc
					});
				mapContent.scene.addLayer(lineLayer);
				//自动缩放
				lineLayer.setAutoFit(true);
				// mapContent.scene.fitBounds([arr[0], arr[arr.length - 1]]);

				//添加结束marker
				let last = dataList[dataList.length - 1];
				addMarker({ ...last, location: last }, true);
			}
		};
		const initMarker = (data: MarkerDataInfo, goto: boolean = true) => {
			if (data) {
				// 创建默认初始化marker
				addMarker(data, goto);
			} else if (props.example) {
				addMarker({ location: { lng: 121.4316962, lat: 31.26082325 } }, goto);
			}
		};
		const initPopupInfo = (marker: Marker) => {
			let lnglat = marker.getLnglat();
			const popup = new Popup({
				lngLat: lnglat,
				anchor: "top",
				closeOnClick: true,
				closeOnEsc: true
			});
			let info = marker.getExtData();
			popup.on("open", async e => {
				let content = await getPopupHtml(info);
				popup.setHTML(content);
			});
			return popup;
		};
		const getPopupHtml = async (info: MarkerDataInfo) => {
			info.location = await getAddress(info.location);
			return `<div class="marker-popup">
				${
					info.devSn
						? `<div class="flex">
								<div class="label">设备:</div>
								<div>${info.devSn}</div>
							</div>`
						: ""
				}
				${
					info.updateTime
						? `<div class="flex">
								<div class="label">时间:</div>
								<div>${info.updateTime}</div>
							</div>`
						: ""
				}
				<div class="flex">
					<div class="label">经度:</div>
					<div>${info.location?.lng}</div>
				</div>
				<div class="flex">
				<div class="label">纬度:</div>
					<div>${info.location?.lat}</div>
				</div>
				<div class="flex">
				<div class="label">地址:</div>
					<div>${info.location?.address}</div>
				</div>
				</div>`;
		};
		const initEvents = () => {
			//点击地图添加marker
			if (props.editerMarker) {
				mapContent.scene.on("click", (ev: any) => {
					if (!mapContent.marker) {
						// let gcjPt = gpsConvert.gcj_decrypt(ev.lnglat.lat, ev.lnglat.lng);
						// addMarker({ location: { lat: gcjPt.lat, lng: gcjPt.lon } }, true);
						addMarker({ location: ev.lnglat }, true);
					} else {
						mapContent.marker.setLnglat(ev.lnglat);
					}
					setLocation(ev.lnglat);
				});
			}
		};
		const setLocation = async (lnglat: LngLat) => {
			let address: LngLat = await getAddress(lnglat);
			if (props.detail) {
				props.detail.location = address;
			}
			emit("location", address);
		};
		const addMarker = async (data: MarkerDataInfo | undefined, goto: boolean) => {
			let dataInfo: MarkerDataInfo = data || props.detail || { location: {} };
			if (dataInfo.location) {
				dataInfo.location.lat = dataInfo.location?.latitude || dataInfo.location?.lat;
				dataInfo.location.lng = dataInfo.location?.longitude || dataInfo.location?.lng;
			}
			//无效位置
			if (!dataInfo.location.lat || !dataInfo.location.lng) {
				mapContent.scene.removeAllMakers();
				return;
			}

			//纠偏
			if (!props.editerMarker) {
				let gcjPt = gpsConvert.gcj_encrypt(dataInfo.location.lat, dataInfo.location.lng);
				dataInfo.location.lat = gcjPt.lat;
				dataInfo.location.lng = gcjPt.lon;
			}
			let lnglat: LngLat = dataInfo.location;
			if (!mapContent.marker) {
				mapContent.marker = new Marker();
				mapContent.marker.setLnglat(lnglat);
				mapContent.marker.setExtData(dataInfo);
				mapContent.marker.setPopup(initPopupInfo(mapContent.marker));
				mapContent.marker.on("click", () => {
					mapContent.marker.openPopup();
				});
				mapContent.scene.addMarker(mapContent.marker);
			} else {
				mapContent.marker.setLnglat(lnglat);
				mapContent.marker.setExtData(dataInfo);

				let popupContent = await getPopupHtml(dataInfo);
				mapContent.marker.getPopup().setHTML(popupContent);
			}
			if (goto) {
				setLocation(lnglat);
				// mapContent.scene.panTo(lnglat);
				mapContent.scene.setCenter([lnglat.lng, lnglat.lat]);
				// mapContent.scene.fitBounds([[lnglat.lng, lnglat.lat]]);
			}
		};
		expose({ initLine, initMarker });
		return () => {
			return (
				<div class="w-full h-full relative">
					<div class="absolute right-4 top-2" style="z-index:9">
						<div class="flex items-center border margin:15px">
							<el-input
								class="flex-1"
								size="small"
								type="primary"
								prefix-icon="Search"
								v-model={searchKeywords.value}
								onInput={searchPlace}
								placeholder={proxy?.$t("basemap.placeholder.search")}
								clearable
							></el-input>
						</div>
						{searchKeywords.value ? <div id="panel"></div> : null}
					</div>
					<div style="min-height: 100px; justify-content: center;position: relative;height:100%;overflow:hidden" id="map" />
				</div>
			);
		};
	}
});
